package demo.practice.competition;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//5848
public class LockingTree {
    Map<Integer, Integer> tree = new HashMap<>();
    Map<Integer, List<Integer>> childs = new HashMap<>();
    Map<Integer, Integer> lock = new HashMap<>();
    int unlock = 0;

    /**
     * ["LockingTree","upgrade","upgrade","unlock","lock","upgrade"]
     * [[[-1,0,3,1,0]],[4,5],[3,8],[0,7],[2,7],[4,6]]
     *  [null,true,false,false,false,false,true,true,false,false,false,false,false,true,false,true,false,false,false,true,false,false,false,true,false,false,false,true,false,false,true,false,false,false,false,false,true,false,false,true,true,false,false,false,false,false,false,false,false,true,false,true,false,false,true,false,false,false,false,false,false,false,true,true,true,false,false,false,false,false,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,true,true,false]
        [null,true,false,false,false,false,true,true,false,false,false,false,false,true,false,true,false,false,false,true,false,false,false,true,false,false,false,true,false,false,true,false,false,false,false,false,true,false,false,false,true,false,false,false,false,false,false,false,false,true,false,true,false,false,true,false,false,false,false,false,false,false,true,true,true,false,false,false,false,false,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,true,true,false]
     *  0
         * 1  4
     *    3
     *   2
     * @param args
     */


    public static void main(String[] args) {
        LockingTree lockingTree = new LockingTree(new int[]{-1,0,3,1,0});
        System.out.println(lockingTree.upgrade(4,5));
        System.out.println(lockingTree.upgrade(3, 8));
        System.out.println(lockingTree.unlock(0, 7));
        System.out.println(lockingTree.lock(2, 7));
        System.out.println(lockingTree.upgrade(4, 6));



    }

    public LockingTree(int[] parent) {
        for (int i = 0; i < parent.length; i++) {
            tree.put(i, parent[i]);
            if (childs.get(parent[i]) == null) {
                childs.put(parent[i], new ArrayList<>());
            }
            childs.get(parent[i]).add(i);
        }
    }

    public boolean lock(int num, int user) {
        //lock.put(num, user);
        if (!lock.containsKey(num)) {
            lock.put(num, user);
            return true;
        } else {
            return false;
        }
    }

    public boolean unlock(int num, int user) {
        if (lock.get(num) != null && lock.get(num) == user) {
            lock.remove(num);
            return true;
        } else {
            return false;
        }
    }

    public boolean upgrade(int num, int user) {
        if (lock.containsKey(num)) {
            return false;
        } else {
            //所有父亲节点没有锁
            int cur = num;
            while (cur != -1) {
                if (lock.containsKey(cur)) {
                    return false;
                }
                cur = tree.get(cur);
            }
            unlock = 0;
            //至少有一个子节点为上锁
            dfsUnlock(num);
            if (unlock > 0) {
                lock(num, user);
                return true;
            }
            return false;
        }
    }

    public void dfsUnlock(int cur) {
        if (lock.containsKey(cur)) {
            lock.remove(cur);
            unlock++;
        } else if (childs.containsKey(cur)) {
            List<Integer> chs = childs.get(cur);

            for (Integer ch : chs) {
                dfsUnlock(ch);
            }

        }
    }
}
